package com.jt;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.StringUtils;

import java.util.List;

@SpringBootTest
public class UserMyBatis {

    //明确 ：注入一定是对象
    //SpringBoot为了整合MyBatis，简化代码结构 Spring动态的为MyBatis的接口创建代理对象
    //代理 ：根据原有对象的模型，在运行期间动态创建了一个一模一样功能的实例化对象
    //案例 ：克隆
    @Autowired
    private UserMapper userMapper;

    @Test
    public void testGetAll() {
        System.out.println(userMapper.getClass());
        //userMapper.getAll().forEach(us -> System.out.println(us));
        userMapper.getAll().forEach(System.out::println);//(souc)
    }

    @Test
    public void testInsert() {
        User user1 = new User();
        user1.setName("MP").setAge(16).setSex("null");
        userMapper.insert(user1);
    }

    @Test
    public void testSelectById() {
        System.out.println(userMapper.selectById(1));
    }

    @Test
    public void testSelectByName() {
        //创建条件构造器 封装where条件
        User user = new User();
        user.setName("小乔").setSex("男");
        //实现时会动态的根据对象中不为null的属性，拼接where条件
        //默认的关系连接符 and
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
        userMapper.selectList(queryWrapper).forEach(System.out::println);

        userMapper.selectList(new QueryWrapper<>(new User().setName("小乔"))).forEach(System.out::println);
    }

    @Test
    public void testSelectByName02() {
        //连续赋值需要指定泛型
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", "小乔")
                .eq("sex", "男");
        userMapper.selectList(queryWrapper).forEach(System.out::println);
    }

    @Test
    public void testSelect03() {
        //EQ -- EQUAL          等于
        //NE -- NOT EQUAL      不等于
        //GT -- GREATER THAN   大于　
        //LT -- LESS THAN      小于
        //逻辑运算符 > gt , < lt , = eq , >= ge , <= le , != ne
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.gt("age", "18")//年龄大于18
                .eq("sex", "女");//性别为女
        //SELECT id,name,age,sex FROM demo_user WHERE (age > ? AND sex = ?)
        //18(String), 女(String)
        userMapper.selectList(userQueryWrapper).forEach(System.out::println);
    }

    @Test
    public void testSelect04() {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //userQueryWrapper.like("name", "乔");
        userQueryWrapper.likeLeft("name", "乔");
        //SELECT id,name,age,sex FROM demo_user WHERE (name LIKE ?)
        //%乔(String)
        userMapper.selectList(userQueryWrapper).forEach(System.out::println);
    }

    @Test
    public void testSelect05() {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.in("id", 1, 2, 6, 88);
        //可变参数（实质是一个数组，定义时，放在方法的最后一位...），用的较少，前端传过来的为数组
        //SELECT id,name,age,sex FROM demo_user WHERE (id IN (?,?,?,?))
        //1(Integer), 2(Integer), 6(Integer), 88(Integer)
        userMapper.selectList(userQueryWrapper).forEach(System.out::println);
    }

    @Test
    public void testSelect06() {
        //一般数组采用包装类型，使用对象身上的方法  基本类型没有方法
        Integer[] ids = {1, 3, 6, 9};
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.in("id", ids);
        //SELECT id,name,age,sex FROM demo_user WHERE (id IN (?,?,?,?))
        //1(Integer), 3(Integer), 6(Integer), 9(Integer)
        userMapper.selectList(userQueryWrapper).forEach(System.out::println);
    }

    /**
     * 关键字 order by 排序  默认 升序 asc / 降序为desc
     * 需求：查询性别为男，年龄降序
     */
    @Test
    public void testSelect07(){
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("sex", "男")
                .orderByDesc("age","id");//先按age排序，如果相等再按照id排序
        //SELECT id,name,age,sex FROM demo_user WHERE (sex = ?) ORDER BY age DESC,id DESC
        //男(String)
        userMapper.selectList(userQueryWrapper).forEach(System.out::println);
    }

    /**
     * 动态Sql:
     *  根据用户的条件,动态的拼接where条件
     *  案例: 根据name,age查询数据
     *  1.select * from demo_user where age > 18 and name="小乔"
     *  API说明:
     *      queryWrapper.gt(判断条件,字段名称,字段值)
     *      判断条件: true  则动态的拼接where条件
     *               false 不会拼接where条件
     *  判断语句:
     *       Boolean nameBoo = (name !=null) && name.length()>0;
     *       boolean nameBoo = StringUtils.hasLength(name);
     *       选择Spring框架的API，为了保证可以通用
     *       import org.springframework.util.StringUtils;
     */
    @Test
    public void testSelect08(){
        Integer age = null;
        String name = "小乔 ";
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        boolean ageBoo = (age != null);
        boolean nameBoo = StringUtils.hasLength(name);
        userQueryWrapper.gt(ageBoo, "age", age)
                .eq(nameBoo, "name", name);
        //SELECT id,name,age,sex FROM demo_user WHERE (name = ?)
        //小乔 (String)
        userMapper.selectList(userQueryWrapper).forEach(System.out::println);
    }

    /**
     * 练习9: 只获取主键ID的值
     * Sql: select id from demo_user
     */
    @Test
    public void testSelect9(){
        List<Object> idList = userMapper.selectObjs(null);
        System.out.println(idList);
    }

    /**
     * 练习10: 删除name="xxx"的数据
     */
    @Test
    public void testDelete(){
        //删除ID为100的数据
        userMapper.deleteById(100);
        //userMapper.deleteBatchIds(null);
        //删除操作的条件构造器
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("name","xxx");
        userMapper.delete(queryWrapper);
    }

    /**
     * 练习11: 数据修改
     * 案例1:  要求修改id=233 name改为="晚上吃什么"
     * API说明: userMapper.updateById(对象信息)
     */
    @Test
    public void testUpdate(){
        //修改除ID之外的所有不为null的数据,id当作where一位条件
        User user = new User();
        user.setId(233).setName("晚上吃什么");
        userMapper.updateById(user);
    }

    /**
     * 练习12: 数据修改
     * 案例2:  将name=mp的用户改为name="宵夜吃什么" age=20 sex=女
     * API说明:
     *         userMapper.update(对象,修改条件构造器)
     *         对象: 修改后的数据使用对象封装
     *         修改条件构造器: 负责修改的where条件
     */
    @Test
    public void testUpdate2(){
        User user = new User();
        user.setName("宵夜吃什么").setAge(20).setSex("女");
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("name","MP");
        userMapper.update(user,updateWrapper);
    }
}
